//
// file : ipctest.cpp
// date : 09/17/07
//
// 
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "inet_ipc.h"
#include "inet_apc.h"


///* - timer test
/*
void __stdcall my_timer(struct utimer_t *tb)
{
    ipc_print(" [%d] my_timer ticks=%d delay=%d\n", tick_count(), tb->ut_ticks, tb->ut_delay);
}

int main(int argc, char *argv[])
{
    long didx;
    long sid;

ipc_print(" [%d] start..\n", tick_count());

    //didx = ipc_startup(5, 0);  // no heart beat
    didx = ipc_startup(5, 100);  // heart beat 100 ms

    sid  = ipc_session(didx, 0);

    utimer_t  ut;

    memset(&ut, 0, sizeof(ut));

    ut.ut_delay = 900;
    ut.ut_awake = my_timer;
    ipc_loadtmr(sid, &ut);

    ut.ut_delay = 2000;
    ut.ut_awake = my_timer;
    ipc_loadtmr(sid, &ut);

    sleep(1);

    ut.ut_delay = 1000;
    ut.ut_awake = my_timer;
    ipc_loadtmr(sid, &ut);

    sleep(6);

    ipc_shutoff(sid);

    ipc_cleanup( didx );

    printf(" (%s) didx=%d sid=(%d %d) exit\n", argv[0], (int)didx, HIWORD(sid), LOWORD(sid) );

    return 0;
}


*/  // timer test


// udp ping
/*
//
// a timer routine
//
void __stdcall ping_(struct utimer_t *tb)
{
    struct tm *st;
    time_t     tt;
    char      str[200];
    ipccb_t  *ipc = (ipccb_t*)(tb->ut_param);
    int       len;

    time(&tt);
    st = localtime(&tt);

    len = sprintf(str, "Ping to(%s:%d) %.4d%.2d%.2d:%.2d%.2d%.2d\n",
             inet_ntoa(ipc->toaddr.sin_addr), ntohs(ipc->toaddr.sin_port),
             st->tm_year+1900, st->tm_mon+1, st->tm_mday, 
             st->tm_hour, st->tm_min, st->tm_sec);

    len = send(ipc->socket, str, len, 0);

    ipc_print("%s", str);
}

//
// a reader
//
long __stdcall pong_(void *ctx, long len)
{
    ipccb_t  *ipc = (ipccb_t*)ctx;

    // incoming data in ibound
    ipc->ibound[1]='o';

    len += ipc->ipoint;

    ipc->ibound[len] = '\0';

    len = sendto( ipc->socket, ipc->ibound, len, 0, 
                  (struct sockaddr*)&ipc->toaddr, sizeof(ipc->toaddr) );

    ipc_print("[%d]%s", (int)len, ipc->ibound);

    return 0;
}

//
// a reader
//
long __stdcall echo_(void *ctx, long len)
{
    ipccb_t  *ipc = (ipccb_t*)ctx;

    // incoming data in ibound
    ipc->ibound[1]='o';

    len += ipc->ipoint;

    ipc->ibound[len] = '\0';

    ipc_print("echo %s", ipc->ibound);

    return 0;
}

long udp_ping(char *addr_str, long didx)
{
    long sid;
    long e;

    sid  = udp_session(didx);  // ipc block for udp

    if( sid < 0 )
    {
        printf(" udp_ping: udp_session=%d\n", (int)sid);
        return sid; // error
    }
    // set reader
    e = set_freader(sid, echo_);

    e = udp_connect(sid, addr_str);

    if( e < 0 )
    {
        printf(" udp_ping: udp_connect(%s)=%d\n", addr_str, (int)e);
        return e;
    }
    // set ping timer
    utimer_t  ut;

    memset(&ut, 0, sizeof(ut));

    ut.ut_cycle = 1000;
    ut.ut_delay = 1500;
    ut.ut_awake = ping_;
    ut.ut_param = ipc_context(sid);

    ipc_loadtmr(sid, &ut);

    return sid;
}

long udp_pong(char *addr_str, long didx)
{
    long sid;
    long e;

    sid  = udp_session(didx);

    if( sid < 0 )
    {
        printf(" udp_pong: udp_session=%d\n", (int)sid);
        return sid; // error
    }

    // set reader
    e = set_freader(sid, pong_);

    e = udp_binding(sid, addr_str);

    if( e < 0 )
    {
        printf(" udp_ping: udp_binding(%s)=%d\n", addr_str, (int)e);
        return e;
    }

    return sid;
}

#include <signal.h>

static int g_quit = 0;

void sig_int(int sig)
{
    if( sig == SIGINT ) g_quit = 1;
}


int main(int argc, char *argv[])
{
    unsigned short port;
    unsigned long  addr;
    long didx=0;
    long sid;

    port = 0;
    addr = 0;

    if( argc < 3 )
    {
print_help:
        printf("Uasge:\t%s {ping|pong} [ip addr:]port\n", argv[0]);
        return 0;
    }

    signal(SIGINT, sig_int);

    if( strcmp( argv[1], "ping") == 0 )
    {
        didx = ipc_startup(5, 0);

        sid = udp_ping( argv[2], didx );
    }
    else if( strcmp( argv[1], "pong") == 0 )
    {
        didx = ipc_startup(5, 0);

        sid = udp_pong( argv[2], didx );
    }
    else goto print_help;

    while( sid > 0 && g_quit == 0 ) sleep(1);
	printf(" <<< exit >>>\n");
    if( didx )
    {
        if( sid > 0 ) ipc_shutoff( sid );
    }

    ipc_cleanup( didx);

    return 0;
}

*/ //udp ping 


/* tcp ping */
//
#include <signal.h>

static int g_quit = 0;

void sig_int(int sig)
{
    if( sig == SIGINT ) g_quit = 1;
}

long __stdcall tpong(void *ctx, long len)
{
    ipccb_t  *ipc = (ipccb_t*)ctx;

    // incoming data in ibound
    ipc->ibound[1]= 'o'; //Ping->Pong

    ipc->ipoint += len;

    ipc->ibound[len] = '\0';

    len = send( ipc->socket, ipc->ibound, ipc->ipoint, 0); 

    ipc_print("[%d]%s", len, ipc->ibound);

    return 0;
}

// tcp server
long tcp_pong(char *addr_str, long didx)
{
    long sid;
    long e;

    sid  = tcp_service(didx, addr_str, 0);

    if( sid < 0 )
    {
        printf(" tcp_pong: tcp_service=%d\n", (int)sid);
        return sid; // error
    }

    // set reader
    e = set_freader(sid, tpong);


    if( e < 0 )
    {
        printf(" tcp_echo: tcp_echo(%s)=%d\n", addr_str, (int)e);
        return e;
    }

    return sid;
}

//
// a timer routine
//
long __stdcall tping(void *ctx)
{
    struct tm *st;
    time_t     tt;
    ipccb_t   *ipc = (ipccb_t*)ctx;
    int        len;

    time(&tt);
    st = localtime(&tt);

    ipc->ocount = sprintf(ipc->obound,
                          "Ping to(%s:%d) %.4d%.2d%.2d:%.2d%.2d%.2d\n",
                          inet_ntoa(ipc->toaddr.sin_addr),
                          ntohs(ipc->toaddr.sin_port),
                          st->tm_year+1900, st->tm_mon+1, st->tm_mday,
                          st->tm_hour, st->tm_min, st->tm_sec);
 
    len = send(ipc->socket, ipc->obound, ipc->ocount, 0);

	ipc_print("[%d]%s", len, ipc->obound);

    ipc->ocount = 0;  // must clear ocount or it be sent twice

    return 0;
}

long __stdcall techo(void *ctx, long len)
{
    ipccb_t  *ipc = (ipccb_t*)ctx;

    // incoming data in ibound
    len += ipc->ipoint;

    ipc->ibound[len] = '\0';

    ipc_print("echo %s", ipc->ibound);

    //SetEvent( ipc->usrobj[0] );

    return 0;
}

long tcp_ping(char *addr_str, long didx)
{
    long sid;
    long e;

    sid  = tcp_session(didx);  // ipc block for udp

    if( sid < 0 )
    {
        printf(" tcp_ping: tcp_session=%d\n", (int)sid);
        return sid; // error
    }
    // set reader
    e = set_freader(sid, techo);
    e = set_ftready(sid, tping);

    //set_userobj(sid, 0, h);

    e = tcp_connect(sid, addr_str);

    if( e < 0 )
    {
        printf(" tcp_ping: tcp_connect(%s)=%d\n", addr_str, (int)e);
        return e;
    }

    return sid;
}

int main(int argc, char *argv[])
{
    unsigned short port;
    unsigned long  addr;
    long didx=0;
    long sid;

    port = 0;
    addr = 0;

    if( argc < 3 )
    {
print_help:
        printf("Uasge:\t%s {ping|pong} [ip addr:]port\n", argv[0]);
        return 0;
    }

    signal(SIGINT, sig_int);

    if( strcmp( argv[1], "ping") == 0 )
    {
        didx = ipc_startup(5, 0);

        sid = tcp_ping( argv[2], didx );

        while( sid > 0 && g_quit == 0 ) pause();
    }
    else if( strcmp( argv[1], "pong") == 0 )
    {
        didx = ipc_startup(5, 0);

        sid = tcp_pong( argv[2], didx );

        while( sid > 0 && g_quit == 0 ) sleep(1);
    }
    else goto print_help;

    if( didx )
    {
        if( sid > 0 ) ipc_shutoff( sid );
    }

    ipc_cleanup( didx);

    printf(" exit..\n");

    return 0;
}

// //tcp_ping 
